<!--
 * @Descripttion: 边界条件泥沙/流量图表
 * @version: 
 * @Author: xcb
 * @Date: 2021-03-16 09:48:46
 * @LastEditors: gzy 810461372@qq.com
 * @LastEditTime: 2023-08-09 16:08:39
-->
<template>
  <el-row style="height: 100%">
    <el-col :span="18">
      <div :id="elementId" style="width: 100%; height: 100%"></div>
    </el-col>
    <el-col :span="6">
      <el-tabs type="card" v-model="activeName" style="height: 90%">
        <el-tab-pane
          v-for="(item, key, i) in tableData"
          :key="i"
          :name="i"
          :label="getTableName(key)"
        >
          <el-table
            border
            stripe
            size="small"
            :data="item"
            :columns="tableColumns"
            :rowKey="(record) => record.tm"
            :customRow="(record) => tableRowClick(record, key)"
            style="width: 100%"
            max-height="255px"
          >
            <el-table-column
              v-for="item in tableColumns"
              :key="item.key"
              :label="item.title"
            >
              <template v-if="item.key == 'tm'" #default="scope">
                {{ scope.row.tm }}
              </template>
              <template v-else #default="scope">
                <el-input
                  v-if="editableData[scope.row.tm]"
                  v-model:value="editableData[scope.row.tm][item.key]"
                  style="margin: -5px 0"
                />
                <template v-else>
                  {{ scope.row[item.key] }}
                </template>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
      </el-tabs>

      <el-button-group v-if="planDataMsgForm.verifyUser" style="float: right">
        <el-button type="primary" @click="triggerUploadButton">
          导入数据
        </el-button>
        <el-button type="primary" @click="TVDataDownload"> 导出数据 </el-button>
        <el-button type="primary" @click="boundaryConditionDataSubmit">
          保存数据
        </el-button>
      </el-button-group>
    </el-col>
  </el-row>

  <el-upload
    :id="elementId + 'upload'"
    style="display: none"
    action="*"
    accept=".xlsx,.xls"
    :show-file-list="false"
    :before-upload="TVDataUpload"
  >
  </el-upload>
</template>

<script lang="ts">
import { cloneDeep } from "lodash-es";
import {
  ref,
  defineComponent,
  reactive,
  provide,
  inject,
  watch,
  toRefs,
  onMounted,
  nextTick,
  getCurrentInstance,
} from "vue";
import moment, { Moment } from "moment";
import * as echarts from "echarts";
import { ElMessage } from "element-plus";

import { ycwriteexcel, uploadExcelFile } from "@/request/api";

export default defineComponent({
  name: "proDialog",
  props: {
    // 树状图数据
    treeData: {
      type: Array as any,
      default: () => [],
    },
    // 用户所选站点
    treeSelectStcd: {
      type: Array as any,
      default: () => [],
    },
    // 图表位置
    elementId: {
      type: String,
      default: () => "",
    },
    // 数据类型
    dataType: {
      type: String,
      default: () => "",
    },
  },
  setup: (props, context) => {
    const { proxy }: any = getCurrentInstance();

    const state = reactive({
      // 表格数据
      tableData: {},
      // 表头数据
      tableColumns: [],
      // 表格修改数据
      editableData: {},

      // 表格标签页选中
      activeName: 0,
    });

    // 边界条件数据
    let boundaryConditionData: any = inject("boundaryConditionData");

    // 坝前水位数据(水位站需要用到)
    let schemePresetData: any = inject("schemePresetData");

    // 方案参数信息
    const planDataMsgForm: any = inject("planDataMsgForm");

    watch(
      () => props.treeSelectStcd,
      (value: any, prevCount) => {
        if (props.dataType != "sw") {
          echartInit(
            boundaryConditionData[value[0]][props.dataType],
            "",
            props.dataType
          );
        }
      },
      { deep: true }
    );

    watch(
      () => schemePresetData,
      (value: any, prevCount) => {
        setTimeout(() => {
          echartInit(
            boundaryConditionData[props.treeSelectStcd[0]][props.dataType],
            "",
            props.dataType
          );
        }, 0);
      },
      { deep: true }
    );

    onMounted(() => {
      // 重新根据数据生成图表
      echartInit(
        boundaryConditionData[props.treeSelectStcd[0]][props.dataType],
        "",
        props.dataType
      );
    });

    /**
     * @description: 生成边界echarts图表
     * @param {*} echartsData echarts图表数据
     * @param {*} echartsTitle echarts图表标题
     * @param {*} type 图表类型 ll(流量) ns(泥沙) sw(水位)
     * @return {*}
     */
    function echartInit(echartsData, echartsTitle, type) {
      const elem = document.getElementById(props.elementId);

      let myChart = echarts.getInstanceByDom(elem);

      if (myChart == undefined) {
        myChart = echarts.init(elem);
      }

      // 指定图表的配置项和数据
      let option = {
        title: {
          text: echartsTitle,
          left: "center",
        },
        tooltip: {
          trigger: "axis",
        },
        legend: {
          show: true,
          top: 25,
        },
        grid: {
          left: 60,
          right: 50,
          bottom: 40,
        },
        xAxis: {
          type: "time",
          name: "日期",
          axisLine: {
            show: true,
          },
          axisTick: {
            show: true,
            inside: true,
          },
          axisLabel: {
            formatter: (value) => {
              return moment(value).format("YYYY-MM-DD HH");
            },
          },
        },
        yAxis: {
          type: "value",
          name: "",
          // min: (value) => {
          //   if (type === "ns") {
          //     let min = value.min * 0.99 - 0.005;
          //     return min <= 0 ? 0 : min.toFixed(4);
          //   } else {
          //     return Math.floor(value.min * 0.99);
          //   }
          // },
          // max: (value) => {
          //   if (type === "ns") {
          //     return (value.max * 1.01 + 0.005).toFixed(4);
          //   } else {
          //     return Math.round(value.max * 1.01);
          //   }
          // },
          scale: true,
          axisLine: {
            show: true,
          },
          axisTick: {
            show: true,
            inside: true,
          },
        },
        series: [],
      };

      // 在源数据中取用的数据字段
      let dataType = "";

      // 判断数据类型
      switch (type) {
        case "ll":
          option.yAxis.name = "流量(m³/s)";
          dataType = "q";

          // 生成右侧表格表头
          state.tableColumns = [
            {
              title: "日期",
              dataIndex: "tm",
              key: "tm",
              width: "60%",
              slots: { customRender: "tm" },
              align: "center",
            },
            {
              title: "流量(m³/s)",
              dataIndex: "q",
              key: "q",
              width: "40%",
              slots: { customRender: "q" },
              align: "center",
            },
          ];
          break;
        case "sw":
          option.yAxis.name = "水位(m)";
          dataType = "z";

          // 生成右侧表格表头
          state.tableColumns = [
            {
              title: "日期",
              dataIndex: "tm",
              key: "tm",
              width: "60%",
              slots: { customRender: "tm" },
              align: "center",
            },
            {
              title: "水位(m)",
              dataIndex: "z",
              key: "z",
              width: "40%",
              slots: { customRender: "z" },
              align: "center",
            },
          ];
          break;
        case "ns":
          option.yAxis.name = "泥沙(kg/m³)";
          dataType = "s";

          // 生成右侧表格表头
          state.tableColumns = [
            {
              title: "日期",
              dataIndex: "tm",
              key: "tm",
              width: "60%",
              slots: { customRender: "tm" },
              align: "center",
            },
            {
              title: "泥沙(kg/m³)",
              dataIndex: "s",
              key: "s",
              width: "40%",
              slots: { customRender: "s" },
              align: "center",
            },
          ];
          break;
      }

      // 生成表格数据前将参数重置
      state.tableData = {};

      // 水文站的预报数据根据坝前水位生成
      if (
        type === "sw" &&
        Object.keys(schemePresetData).length != 0 &&
        planDataMsgForm.predictDay != 0
      ) {
        // 根据坝前水位修改边界数据
        echartsData.yb = schemePresetData.swjList.map((item) => {
          return {
            stcd: echartsData.real[0].stcd,
            tm: item.ymdh,
            z: item.z,
          };
        });
      }

      // 循环站点内数据
      for (const key in echartsData) {
        // 将站点内数据生成echarts线段数据
        let obj = {
          name: "",
          type: "line",
          data: echartsData[key].map((item) => [
            moment(item.tm).format("YYYY-MM-DD HH:mm:ss"),
            item[dataType],
          ]),
          showSymbol: false,
          lineStyle: {
            color: "",
          },
          itemStyle: {
            color: "",
          },
        };

        // 判断站点内数据类型
        switch (key) {
          case "zb":
            obj.name = "整编数据";
            obj.lineStyle.color = "#ff0000";
            obj.itemStyle.color = "#ff0000";
            break;
          case "real":
            obj.name = "报汛数据";
            obj.lineStyle.color = "#7030a0";
            obj.itemStyle.color = "#7030a0";
            break;
          case "tt":
            obj.name = "推算数据";
            obj.lineStyle.color = "#00b050";
            obj.itemStyle.color = "#00b050";
            break;
          case "yb":
            obj.name = "预报数据";
            obj.lineStyle.color = "#ffc000";
            obj.itemStyle.color = "#ffc000";
            break;
          case "zdy":
            obj.name = "自定义数据";
            obj.lineStyle.color = "#767171";
            obj.itemStyle.color = "#767171";
            break;
        }

        option.series.push(obj);

        // 生成右侧表格数据
        state.tableData[key] = echartsData[key].map((item) => {
          return {
            tm: moment(item.tm).format("YYYY-MM-DD HH:mm:ss"),
            [dataType]: item[dataType],
            stcd: item.stcd,
          };
        });
      }

      myChart.setOption(option, true);

      setTimeout(() => {
        myChart.resize();
      }, 0);

      window.addEventListener("resize", () => {
        myChart.resize();
      });
    }

    /**
     * @description: 右侧表格生成标签页名字
     * @param {*} key
     * @return {*}
     */
    function getTableName(key) {
      let name;
      switch (key) {
        case "zb":
          name = "整编数据";
          break;
        case "real":
          name = "报讯数据";
          break;
        case "tt":
          name = "推算数据";
          break;
        case "yb":
          name = "预报数据";
          break;
        case "zdy":
          name = "自定义数据";
          break;
      }
      return name;
    }

    /**
     * @description: 触发文件上传按钮
     * @return {*}
     */
    function triggerUploadButton() {
      // 获取当前页面隐藏的文件上传组件下的input按钮
      let uploadDomElement: any = document
        .getElementById(props.elementId + "upload")
        .getElementsByClassName("el-upload__input")[0];

      // 触发input按钮的点击事件
      uploadDomElement.click();
    }

    /**
     * @description: 文件上传
     * @param {*} file 文件对象
     * @return {*}
     */
    function TVDataUpload(file) {
      uploadExcelFile({
        file,
      }).then((res: any) => {
        // 需要修改的数据字段
        let dataType = "";

        // 判断数据类型
        switch (props.dataType) {
          case "ll":
            dataType = "q";
            break;
          case "sw":
            dataType = "z";
            break;
          case "ns":
            dataType = "s";
            break;
        }

        // 将返回数据根据类型处理为不同数据
        const data = {
          real: res.data.map((item) => {
            return {
              tm: item.time,
              [dataType]: item.data,
              stcd: props.treeSelectStcd[0],
            };
          }),
        };

        // 生成图表
        echartInit(data, "", props.dataType);
      });

      // 组件上传固定返回值
      return false;
    }

    /**
     * @description: 保存当前图表中数据
     * @return {*}
     */
    function boundaryConditionDataSubmit() {
      // 用户所选站点
      let selectStcd: any = props.treeSelectStcd[0];

      // 将右侧表格数据保存到源数据中
      boundaryConditionData[selectStcd][props.dataType] = state.tableData;
    }

    /**
     * @description: 导出数据
     * @return {*}
     */
    function TVDataDownload() {
      let yname,
        riverNm = props.treeData.find(
          (item: any) => item.key === props.treeSelectStcd[0]
        ).title;

      let dataList = Object.values<any[]>(state.tableData) // 取出对象中的value组成二维数组
        .reduce((previousValue: Array<[]>, currentValue: Array<[]>) =>
          previousValue.concat(currentValue)
        ) // 将二维数组多项合并为一个数组
        .map((item) => {
          // 根据类型处理导出数据以及修改导出y轴名字
          switch (props.dataType) {
            case "ll":
              yname = "流量";

              return {
                dt: item.tm,
                t: item.q,
              };
            case "sw":
              yname = "水位";

              return {
                dt: item.tm,
                t: item.z,
              };
            case "ns":
              yname = "含沙量";

              return {
                dt: item.tm,
                t: item.s,
              };
          }
        });

      let obj = {
        dataList,
        riverNm,
        yname,
        name: riverNm + " " + yname,
      };

      ycwriteexcel(obj).then((res) => {});
    }

    return {
      props,
      ...toRefs(state),

      getTableName,

      triggerUploadButton,

      TVDataUpload,
      boundaryConditionDataSubmit,

      TVDataDownload,
      planDataMsgForm,
    };
  },
});
</script>

<style scoped lang="less"></style>
